import tkinter as tk
from tkinter import messagebox, Canvas, Button, Label, Tk, Entry, Toplevel
import os
from PIL import Image, ImageDraw, ImageTk, ImageGrab
import numpy as np
import tensorflow as tf
import sqlite3

# Initialize SQLite connection and cursor
conn = sqlite3.connect('users.db')
c = conn.cursor()

# Create table to store user credentials
c.execute('''CREATE TABLE IF NOT EXISTS users
             (username TEXT PRIMARY KEY, password TEXT)''')
conn.commit()

# Digit Recognition GUI
def run_digit_recognition_app():
    def clear_canvas():
        canvas.delete('all')  # 删除画布上的所有元素
        img_draw.rectangle([(20, 0), (300, 280)], fill='black')  # 在图像上绘制一个黑色的矩形覆盖原有内容
        output_label.config(text='')
 
 
    def draw(event):
        x, y = event.x, event.y
        canvas.create_text(x, y, text='●', font='Helvetica 20', fill='white')  # 将椭圆填充颜色设为白色
        img_draw.ellipse([(x - 5, y - 5), (x + 5, y + 5)], fill='white')  # 将椭圆描边颜色设为白色
 
 
    def recognize_digit():
        # 从画布中获取图像，调整尺寸为模型所需的大小
        image = img.crop((0, 0, 300, 300)).resize((28, 28)).convert('L')

        # 数据预处理
        input_data = np.array(image).reshape((1, 28, 28, 1)).astype('float32')
        input_data = input_data / 255.0  # 将像素值缩放到0到1之间

        # 使用模型进行预测
        with tf.device('/CPU:0'):  # Ensure the model is run on CPU to avoid compatibility issues
            output = model.predict(input_data)
            prediction = np.argmax(output)
    
        result_font = font.Font(size=15)
        # 显示预测结果
        output_label.config(text=f'\n识别结果: {prediction}', font=result_font)
 
    root = tk.Tk()
    root.title("手写数字识别")
 
    # 计算窗口位置
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    window_width = 320
    window_height = 350
    x_position = int((screen_width - window_width) / 2)
    y_position = int((screen_height - window_height) / 2)
    root.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")

    canvas = tk.Canvas(root, width=canvas_width, height=canvas_height, bg='black')


    # 固定窗口大小
    root.resizable(False, False)
    root.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")

    canvas = tk.Canvas(root, width=canvas_width, height=canvas_height, bg='black')
    canvas.pack()

    img = Image.new('RGB', (canvas_width, canvas_height), 'black')
    img_draw = ImageDraw.Draw(img)

    canvas.bind('<B1-Motion>', draw)

    recognize_button = tk.Button(root, text="识别", command=recognize_digit, width=10, height=2)
    recognize_button.pack(side=tk.LEFT, padx=10, pady=10)

    clear_button = tk.Button(root, text="清除", command=clear_canvas, width=10, height=2)
    clear_button.pack(side=tk.RIGHT, padx=10, pady=10)

    output_label = tk.Label(root, text='', font=('Arial', 20))
    output_label.pack()

    root.mainloop()

# Function to register a new user
def register_user(username, password):
    try:
        c.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, password))
        conn.commit()
        messagebox.showinfo("注册成功", "您已成功注册。")
    except sqlite3.IntegrityError:
        messagebox.showerror("注册失败", "用户名已存在。")

# Function to authenticate user
def authenticate_user(username, password):
    c.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))
    return c.fetchone() is not None

# Function to open registration window
def open_registration_window():
    registration_window = Toplevel(root)
    registration_window.title("注册界面")

    # Labels and entry widgets for new username, password, and confirm password
    new_username_label = Label(registration_window, text="新用户名:")
    new_username_label.grid(row=0, column=0, padx=10, pady=5)
    new_username_entry = Entry(registration_window)
    new_username_entry.grid(row=0, column=1, padx=10, pady=5)

    new_password_label = Label(registration_window, text="新密码:")
    new_password_label.grid(row=1, column=0, padx=10, pady=5)
    new_password_entry = Entry(registration_window, show="*")
    new_password_entry.grid(row=1, column=1, padx=10, pady=5)
    
    confirm_password_label = Label(registration_window, text="确认密码:")
    confirm_password_label.grid(row=2, column=0, padx=10, pady=5)
    confirm_password_entry = Entry(registration_window, show="*")
    confirm_password_entry.grid(row=2, column=1, padx=10, pady=5)

    # Button to submit registration
    register_button = Button(registration_window, text="注册", command=lambda: register_new_user(
        new_username_entry.get(), new_password_entry.get(), confirm_password_entry.get()))
    register_button.grid(row=3, column=0, columnspan=2, padx=10, pady=5)

# Function to register a new user
def register_new_user(new_username, new_password, confirm_password):
    if len(new_username) < 5:
        messagebox.showerror("注册失败", "用户名长度至少应为5个字符")
        return
    
    if len(new_password) < 8:
        messagebox.showerror("注册失败", "密码长度至少应为8个字符")
        return
    
    if new_username.isalnum() and new_password.isalnum():
        if new_password == confirm_password:
            register_user(new_username, new_password)
        else:
            messagebox.showerror("注册失败", "确认密码与密码不一致。")
    else:
        messagebox.showerror("注册失败", "用户名和密码只能包含字母和数字。")

# Function to authenticate and run digit recognition
def authenticate_and_run_digit_recognition():
    username = username_entry.get()
    password = password_entry.get()

    if authenticate_user(username, password):
        messagebox.showinfo("登录成功", "您已成功登录。")
        run_digit_recognition_app()  # 登录成功后调用手写数字识别应用
    else:
        messagebox.showerror("登录失败", "用户名或密码错误。")
        if not username.isalnum() or not password.isalnum():
            messagebox.showerror("登录失败", "用户名和密码只能包含字母和数字。")

# Rest of your code remains unchanged

# Main login window
root = tk.Tk()
root.title("登录界面")

# Labels and entry widgets for username and password
username_label = Label(root, text="用户名:")
username_label.grid(row=0, column=0, padx=10, pady=5)
username_entry = Entry(root)
username_entry.grid(row=0, column=1, padx=10, pady=5)

password_label = Label(root, text="密码:")
password_label.grid(row=1, column=0, padx=10, pady=5)
password_entry = Entry(root, show="*")
password_entry.grid(row=1, column=1, padx=10, pady=5)

# Buttons for login and registration
login_button = Button(root, text="登录", command=authenticate_and_run_digit_recognition)
login_button.grid(row=2, column=0, padx=10, pady=5)

register_button = Button(root, text="注册", command=open_registration_window)
register_button.grid(row=2, column=1, padx=10, pady=5)

root.mainloop()